/*
 ============================================================================
 Name        : Crypto2009-Tp2.c
 Author      : Ana Roig & Pablo Abad
 Version     : 1.0
 Description : Generación de claves para TP2
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "util.h"


#define MAX_NAME_LENGTH 12
#define MAX_USER_KEY_LENGTH 8

#define KEY_SIZE 16
#define STORE_KEY_LENGTH (KEY_SIZE * 2)

#define MAX_USERS 10

typedef struct {
	char name[MAX_NAME_LENGTH ];
	char key[MAX_USER_KEY_LENGTH + 1];
	char storekey[STORE_KEY_LENGTH +1];
} User;


User** readUsers(char *file, int *total) {
	FILE *usuarios;
	User **users;
	char line[81];
	char *current;
	int count = 0;

	users = calloc(sizeof(User *), MAX_USERS);

	if ((usuarios = fopen(file ,"r")) == NULL) {
		printf("No se pudo abrir el archivo %s: %s", file, strerror(errno));
		exit(1);
	}
	
	while ((current = fgets(line, 80, usuarios)) != NULL) {
		users[count] = malloc(sizeof(User));
		
		strcpy(users[count]->name, strtok(current, ":\n"));
		strcpy(users[count]->key, strtok(NULL, ":\n"));
		
		if (++count == MAX_USERS) {
			printf("Hay demasiados usuarios!");
			exit(1);
		}
	}
	
	*total = count;
	return users;
}

void printUsers(User **users, int count) {
	int i;
	for (i=0;i<count; i++) {
		printf("%s:%s\n", users[i]->name, users[i]->storekey);
	}
}

void encodePassword(User *user, unsigned char *key) {
	unsigned char hash[SHA_DIGEST_LENGTH];
	char buffer[80];
	int i;

	strcpy(buffer, user->name);
	strcat(buffer, user->key);

	calculateHash(hash, buffer);

	for (i=0; i<16;i++) {
		hash[i] ^= key[i];
	}
	for (i=16; i<SHA_DIGEST_LENGTH; i++) {
		hash[i] = 0;
	}

	byte2hex(user->storekey, hash, 16);
}

void encodePasswords(User **users, int count, unsigned char *key) {
	int i;

	for (i=0;i<count; i++) {
		encodePassword(users[i], key);
	}
}

int main(int argc, char **argv) {
	User **users;
	unsigned char key[KEY_SIZE];
	int count, i;

	if (argc != 3) {
		printf("Forma de invocacion: %s <archivo claves> <clave en hexadecimal>", argv[0]);
		exit(1);
	}

	users = readUsers(argv[1], &count);
	printf("key ingresada=%s\n", argv[2]);
	hex2byte(key, argv[2], KEY_SIZE);
	printf("key procesada antes de codear=%s\n", key);

	for( i=0 ; i< 16 ; i++)
		printf("key[%d]=%2X\n",i, key[i]);

	encodePasswords(users, count, key);
	printUsers(users, count);
	return EXIT_SUCCESS;
}

